package com.colin.juc.flowcontrol.semaphore;

import java.util.List;
import java.util.Vector;
import java.util.concurrent.Semaphore;
import java.util.function.Function;

/**
 * Created by zhaodong on 2021/5/7 11:5529
 * email: colinzhaodong@gmail.com
 * desc:
 *
 * @author zhaodong
 */
public class ObjPool<T, R> {
    final List<T> pool;
    // 用信号量实现限流器
    static Semaphore sem;

    // 构造函数
    ObjPool(int size, T t) {
        pool = new Vector<T>() {
        };
        for (int i = 0; i < size; i++) {
            pool.add(t);
        }
        sem = new Semaphore(size);
    }

    // 利用对象池的对象，调用 func
    void exec(Function<T, R> func) throws InterruptedException {
        T t = null;
        if (sem.availablePermits() <= 0 ){
            System.out.println("暂时无法获取到许可证,请稍等片刻");
        }
        sem.acquire();
        try {
            t = pool.remove(0);
            System.out.println(Thread.currentThread().getName() + ":可用通行证数量:" + sem.availablePermits());
            func.apply(t);
        } finally {
            pool.add(t);
            sem.release();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // 创建对象池
        ObjPool<Long, String> pool =
                new ObjPool<>(10, 2L);

        for (int i = 0; i < 15; i++) {
            new Thread(() -> {
// 通过对象池获取 t，之后执行
                try {
                    pool.exec(t -> {
                        System.out.println(t);
                        return t.toString();
                    });
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

